package org.jeecg.modules.personalTask.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.ganttTasks.entity.GanttTasks;
import org.jeecg.modules.ganttTasks.service.IGanttTasksService;
import org.jeecg.modules.personalTask.entity.ExtensionDTO;
import org.jeecg.modules.personalTask.entity.PersonalTask;
import org.jeecg.modules.personalTask.entity.PersonalTaskVO;
import org.jeecg.modules.personalTask.service.IPersonalTaskService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.*;

/**
 * @Description: 个人任务
 * @Author: jeecg-boot
 * @Date:   2024-02-18
 * @Version: V1.0
 */
@Api(tags="个人任务")
@RestController
@RequestMapping("/personalTask/personalTask")
@Slf4j
public class PersonalTaskController extends JeecgController<PersonalTask, IPersonalTaskService> {
	@Autowired
	private IPersonalTaskService personalTaskService;
	@Autowired
	private IGanttTasksService ganttTasksService;
	
	/**
	 * 分页列表查询
	 *
	 * @param personalTask
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	@AutoLog(value = "个人任务-分页列表查询")
	@ApiOperation(value="个人任务-分页列表查询", notes="个人任务-分页列表查询")
	@GetMapping(value = "/list")
	public Result<?> queryPageList(PersonalTask personalTask,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		QueryWrapper<PersonalTask> queryWrapper = QueryGenerator.initQueryWrapper(personalTask, req.getParameterMap());
		Page<PersonalTask> page = new Page<PersonalTask>(pageNo, pageSize);
		Integer status = personalTask.getStatus();
		if (status == null){
			queryWrapper.eq("status", 1);
		}
		queryWrapper.eq("sign", 1);
		queryWrapper.orderByAsc("status");
		queryWrapper.orderByDesc("create_time");
		IPage<PersonalTask> pageList = personalTaskService.page(page, queryWrapper);
		return Result.OK(pageList);
	}

	@GetMapping("/getAll")
	public Result<?> getAll(@RequestParam(required = false) String header){
		LambdaQueryWrapper<PersonalTask> wrapper = Wrappers.lambdaQuery();
		if (header != null && !header.isEmpty()){
			wrapper.eq(PersonalTask::getHeader, header);
		}
		wrapper.eq(PersonalTask::getSign, 1);
		wrapper.eq(PersonalTask::getStatus, 1);
		wrapper.orderByAsc(PersonalTask::getStatus);
		wrapper.orderByDesc(PersonalTask::getCreateTime);
		List<PersonalTask> list = personalTaskService.list(wrapper);
		return Result.OK(list);
	}

	@GetMapping("/getOwnerTask")
	public Result<?> getOwnerTask(){
		LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		LambdaQueryWrapper<PersonalTask> wrapper = Wrappers.lambdaQuery();
		wrapper.eq(PersonalTask::getHeader, user.getRealname());
		wrapper.eq(PersonalTask::getStatus, 1);
		wrapper.eq(PersonalTask::getSign, 1);
		List<PersonalTask> list = personalTaskService.list(wrapper);
		return Result.OK(list);
	}

	@GetMapping("/getThisWeekTask")
	public Result<?> getThisWeekTask(){
		LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		WeekFields weekFields = WeekFields.of(Locale.getDefault());
		int currentWeek = LocalDate.now().get(weekFields.weekOfWeekBasedYear());

		LambdaQueryWrapper<PersonalTask> wrapper = Wrappers.lambdaQuery();
		wrapper.eq(PersonalTask::getHeader, user.getRealname());
		wrapper.eq(PersonalTask::getStatus, 1);
		wrapper.eq(PersonalTask::getSign, 1);
		wrapper.and(w -> w.apply("WEEK(start_date) = {0}", currentWeek)  // 确保起始时间在本周
				.or()
				.apply("WEEK(end_date) = {0}", currentWeek)  // 确保结束时间在本周
				.or()
				.apply("start_date < {0} AND end_date > {0}", LocalDate.now()));// 确保任务跨越本周
		List<PersonalTask> list = personalTaskService.list(wrapper);
		return Result.OK(list);
	}

	@GetMapping("/getProjectForDailyForm")
	public Result<?> getProjectForDailyForm(){
		LambdaQueryWrapper<GanttTasks> ganttWrapper = Wrappers.lambdaQuery();
		ganttWrapper.eq(GanttTasks::getType, "project");
		List<GanttTasks> ganttTasks = ganttTasksService.list(ganttWrapper);
		GanttTasks project = ganttTasks.get(0);
		LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		LambdaQueryWrapper<PersonalTask> wrapper = Wrappers.lambdaQuery();
		wrapper.eq(PersonalTask::getHeader, user.getRealname());
		wrapper.eq(PersonalTask::getProjectId, project.getId());
		wrapper.eq(PersonalTask::getStatus, 1);
		wrapper.eq(PersonalTask::getSign, 1);
		List<PersonalTask> list = personalTaskService.list(wrapper);
		List<List<?>> allList = new ArrayList<>();
		allList.add(ganttTasks);
		allList.add(list);
		return Result.OK(allList);
	}

	@GetMapping("/getTaskForDailyForm")
	public Result<?> getTaskForDailyForm(@RequestParam String id){
		LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		LambdaQueryWrapper<PersonalTask> wrapper = Wrappers.lambdaQuery();
		wrapper.eq(PersonalTask::getHeader, user.getRealname());
		wrapper.eq(PersonalTask::getProjectId, id);
		wrapper.eq(PersonalTask::getStatus, 1);
		wrapper.eq(PersonalTask::getSign, 1);
		List<PersonalTask> list = personalTaskService.list(wrapper);
		return Result.OK(list);
	}

	@GetMapping("/getDetailById")
	public Result<?> getDetailById(@RequestParam(name = "id") String id){
		PersonalTask byId = personalTaskService.getById(id);
		String parent = byId.getParent();
		LambdaQueryWrapper<PersonalTask> wrapper = Wrappers.lambdaQuery();
		wrapper.orderByDesc(PersonalTask::getUpdateNum);
		if (parent == null || parent.isEmpty()){
			wrapper.eq(PersonalTask::getId, id).or(w -> w.eq(PersonalTask::getParent, id));
        }else {
			wrapper.eq(PersonalTask::getId, parent).or(w -> w.eq(PersonalTask::getParent, parent));
        }
		List<PersonalTask> list = personalTaskService.list(wrapper);
		LambdaQueryWrapper<GanttTasks> ganttWrapper = Wrappers.lambdaQuery();
		ganttWrapper.eq(GanttTasks::getType, "project");
		List<GanttTasks> ganttTasks = ganttTasksService.list(ganttWrapper);
		Map<String, String> ganttMap = new HashMap<>();
		List<PersonalTaskVO> voList = new ArrayList<>();
		for (GanttTasks task : ganttTasks){
			ganttMap.put(task.getId(), task.getText());
		}
		for (PersonalTask personalTask : list){
			PersonalTaskVO personalTaskVO = new PersonalTaskVO();
			BeanUtils.copyProperties(personalTask, personalTaskVO);
			String projectId = personalTask.getProjectId();
			String text = ganttMap.get(projectId);
			if (text != null){
				personalTaskVO.setProjectText(text);
			}
			voList.add(personalTaskVO);
		}
		return Result.OK(voList);
	}

	@GetMapping("/getProgressById")
	public Result<?> getProgressById(@RequestParam(name = "id") String id){
		PersonalTask byId = personalTaskService.getById(id);
		return Result.OK(byId.getProgress());
	}

	@AutoLog(value = "个人任务-测试")
	@ApiOperation(value="个人任务-测试", notes="个人任务-测试")
	@PostMapping(value = "/test")
	public Result<?> test() {
		List<GanttTasks> list = ganttTasksService.list();
		List<PersonalTask> personalTaskList = personalTaskService.list();
		Map<String, PersonalTask> map = new HashMap<>();
		List<PersonalTask> list1 = new ArrayList<>();
		for (PersonalTask personalTask : personalTaskList){
			map.put(personalTask.getGanttId(), personalTask);
		}
		for (GanttTasks ganttTasks : list){
			if (!map.containsKey(ganttTasks.getId()) && "task".equals(ganttTasks.getType())){
				PersonalTask personalTask = new PersonalTask();
				Date start = ganttTasks.getStartDate();
				Calendar c = Calendar.getInstance();
				c.setTime(start);
				c.add(Calendar.DAY_OF_MONTH, ganttTasks.getDuration()-1);
				personalTask.setEndDate(c.getTime());
				personalTask.setStartDate(ganttTasks.getStartDate()).setStatus(1)
						.setDuration(ganttTasks.getDuration())
						.setHeader(ganttTasks.getUsers()).setText(ganttTasks.getText())
						.setPriority(ganttTasks.getPriority()).setAssignor("管理员")
						.setProgress(ganttTasks.getProgress())
						.setUpdateNum(0).setUpdateReason(null)
						.setParent(null).setProjectId(ganttTasks.getParent())
						.setSign(1).setGanttId(ganttTasks.getId());
				list1.add(personalTask);
			}
		}
		personalTaskService.saveBatch(list1);
		return Result.OK("成功！");
	}

	@AutoLog(value = "甘特图-延期")
	@ApiOperation(value="甘特图-延期", notes="甘特图-延期")
	@PostMapping("/extension")
	public Result<?> extension(@RequestBody ExtensionDTO extensionDTO){
		String id = extensionDTO.getId();
		LambdaQueryWrapper<PersonalTask> wrapper = Wrappers.lambdaQuery();
		wrapper.eq(PersonalTask::getGanttId, id);
		wrapper.eq(PersonalTask::getSign, 1);
		PersonalTask one = personalTaskService.getOne(wrapper);
		Integer updateNum = one.getUpdateNum();
		String parent = one.getParent();
		Date start = extensionDTO.getStartDate();
		Calendar c = Calendar.getInstance();
		c.setTime(start);
		c.add(Calendar.DAY_OF_MONTH, extensionDTO.getDuration()-1);

		PersonalTask newTask = new PersonalTask();
		BeanUtils.copyProperties(one, newTask);
		newTask.setId(null).setEndDate(c.getTime()).setUpdateNum(updateNum+1)
				.setSign(1).setUpdateReason(extensionDTO.getUpdateReason());
		if (parent == null || parent.isEmpty()){
			newTask.setParent(one.getId());
		}
		personalTaskService.save(newTask);
		GanttTasks ganttTask = getGanttTask(newTask);
		ganttTasksService.updateById(ganttTask);
		LambdaUpdateWrapper<PersonalTask> updateWrapper = Wrappers.lambdaUpdate();
		updateWrapper.set(PersonalTask::getSign, 0);
		updateWrapper.eq(PersonalTask::getId, one.getId());
		personalTaskService.update(updateWrapper);
		return Result.OK("修改成功！");
	}

	/**
	 *   添加
	 *
	 * @param personalTask
	 * @return
	 */
	@AutoLog(value = "个人任务-添加")
	@ApiOperation(value="个人任务-添加", notes="个人任务-添加")
	@PostMapping(value = "/add")
	public Result<?> add(@RequestBody PersonalTask personalTask) {
		personalTask.setStatus(1);
		personalTask.setProgress(0D);
		Date start = personalTask.getStartDate();
		Date end = personalTask.getEndDate();
		long getTime = end.getTime() - start.getTime();
		int num = (int) (getTime / (1000 * 60 * 60 * 24))+1;
		personalTask.setDuration(num);
		personalTask.setUpdateNum(0);
		personalTask.setSign(1);
		GanttTasks ganttTask = getGanttTask(personalTask);
		ganttTasksService.save(ganttTask);
		personalTask.setGanttId(ganttTask.getId());
		personalTaskService.save(personalTask);
		return Result.OK("添加成功！");
	}
	
	/**
	 *  编辑
	 *
	 * @param personalTask
	 * @return
	 */
	@AutoLog(value = "个人任务-编辑")
	@ApiOperation(value="个人任务-编辑", notes="个人任务-编辑")
	@PutMapping(value = "/edit")
	public Result<?> edit(@RequestBody PersonalTask personalTask) {
		Integer updateNum = personalTask.getUpdateNum();
		String parent = personalTask.getParent();
		Date start = personalTask.getStartDate();
		Date end = personalTask.getEndDate();
		long getTime = end.getTime() - start.getTime();
		int num = (int) (getTime / (1000 * 60 * 60 * 24))+1;

		PersonalTask newTask = new PersonalTask();
		BeanUtils.copyProperties(personalTask, newTask);
		newTask.setId(null).setDuration(num).setUpdateNum(updateNum+1).setSign(1);
		if (personalTask.getStatus() == 2){
			newTask.setProgress(1D);
		}
		if (personalTask.getProgress() == 1){
			newTask.setStatus(2);
		}
		if (parent == null || parent.isEmpty()){
			newTask.setParent(personalTask.getId());
		}
		GanttTasks ganttTask = getGanttTask(newTask);
		ganttTasksService.updateById(ganttTask);
		personalTaskService.save(newTask);
		LambdaUpdateWrapper<PersonalTask> wrapper = Wrappers.lambdaUpdate();
		wrapper.set(PersonalTask::getSign, 0);
		wrapper.eq(PersonalTask::getId, personalTask.getId());
		personalTaskService.update(wrapper);
		return Result.OK("编辑成功!");
	}

	public GanttTasks getGanttTask(PersonalTask personalTask){
		String ganttId = personalTask.getGanttId();
		if (ganttId != null && !ganttId.isEmpty()){
			GanttTasks byId = ganttTasksService.getById(ganttId);
			if (byId != null){
				byId.setStartDate(personalTask.getStartDate())
						.setDuration(personalTask.getDuration())
						.setProgress(personalTask.getProgress())
						.setText(personalTask.getText())
						.setUsers(personalTask.getHeader())
						.setPriority(personalTask.getPriority())
						.setParent(personalTask.getProjectId());
				return byId;
			}
		}
		GanttTasks ganttTasks = new GanttTasks();
		BeanUtils.copyProperties(personalTask, ganttTasks);
		ganttTasks.setParent(personalTask.getProjectId())
				.setProgress(0D).setType("task")
				.setUsers(personalTask.getHeader());
		return ganttTasks;
	}
	
	/**
	 *   通过id删除
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "个人任务-通过id删除")
	@ApiOperation(value="个人任务-通过id删除", notes="个人任务-通过id删除")
	@DeleteMapping(value = "/delete")
	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
		personalTaskService.removeById(id);
		return Result.OK("删除成功!");
	}
	
	/**
	 *  批量删除
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "个人任务-批量删除")
	@ApiOperation(value="个人任务-批量删除", notes="个人任务-批量删除")
	@DeleteMapping(value = "/deleteBatch")
	public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.personalTaskService.removeByIds(Arrays.asList(ids.split(",")));
		return Result.OK("批量删除成功!");
	}
	
	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "个人任务-通过id查询")
	@ApiOperation(value="个人任务-通过id查询", notes="个人任务-通过id查询")
	@GetMapping(value = "/queryById")
	public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
		PersonalTask personalTask = personalTaskService.getById(id);
		if(personalTask==null) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(personalTask);
	}

	@GetMapping("/queryTextById")
	public Result<?> queryTextById(@RequestParam(name="id",required=true) String id){
		PersonalTask byId = personalTaskService.getById(id);
		return Result.OK(byId.getText());
	}

    /**
    * 导出excel
    *
    * @param request
    * @param personalTask
    */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, PersonalTask personalTask) {
        return super.exportXls(request, personalTask, PersonalTask.class, "个人任务");
    }

    /**
      * 通过excel导入数据
    *
    * @param request
    * @param response
    * @return
    */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, PersonalTask.class);
    }

}
